In a runtime environment that uses a virtual machine, such as one that supports the Java language, software can be converted into one or more bytecodes. A bytecode is an instruction that performs one or more relatively low-level operations; e.g., memory loads and stores, register operations, and basic numerical operations. However, a bytecode may not be directly executable on a particular computing device. In contrast, a machine-language instruction for a particular computing device can be directly executed by the particular computing device to perform one or more relatively low-level operations.
To bridge the gap between bytecodes and machine-language instructions, bytecodes can be compiled, which involves converting the bytecodes into machine-language instructions that can be executed on the particular computing device. Another technique for executing bytecodes involves use of an interpreter, or software executable on the particular computing device that can perform operations as specified by the bytecodes. Typically, bytecodes that have been compiled into machine-language instructions can be executed faster than interpreted bytecodes.
Some bytecode compilers can operate as ahead-of-time (AOT) compilers, which compile all of the bytecodes into machine-language instructions in prior to execution of the machine-language instructions; i.e., all machine-language instructions are generated prior to runtime. Some bytecode compilers can operate as a just-in-time (JIT) compiler that compiles bytecodes into machine-language instructions as needed during execution of the software.